package cn.iocoder.yudao.module.ao.service.labschedule;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import cn.iocoder.yudao.module.ao.controller.admin.labschedule.vo.*;
import cn.iocoder.yudao.module.ao.dal.dataobject.labschedule.LabScheduleDO;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;

import cn.iocoder.yudao.module.ao.dal.mysql.labschedule.LabScheduleMapper;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import org.springframework.transaction.annotation.Propagation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Async;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.diffList;
import static cn.iocoder.yudao.module.ao.enums.ErrorCodeConstants.*;

/**
 * 机房实训室课 Service 实现类
 *
 * @author 禾安
 */
@Slf4j
@Service
@Validated
public class LabScheduleServiceImpl implements LabScheduleService {

    @Resource
    private LabScheduleMapper labScheduleMapper;

    @Override
    public Long createLabSchedule(LabScheduleSaveReqVO createReqVO) {
        // 插入
        LabScheduleDO labSchedule = BeanUtils.toBean(createReqVO, LabScheduleDO.class);
        labScheduleMapper.insert(labSchedule);

        // 返回
        return labSchedule.getId();
    }

    @Override
    public void updateLabSchedule(LabScheduleSaveReqVO updateReqVO) {
        // 校验存在
        validateLabScheduleExists(updateReqVO.getId());
        // 更新
        LabScheduleDO updateObj = BeanUtils.toBean(updateReqVO, LabScheduleDO.class);
        labScheduleMapper.updateById(updateObj);
    }

    @Override
    public void deleteLabSchedule(Long id) {
        // 校验存在
        validateLabScheduleExists(id);
        // 删除
        labScheduleMapper.deleteById(id);
    }

    @Override
        public void deleteLabScheduleListByIds(List<Long> ids) {
        // 删除
        labScheduleMapper.deleteByIds(ids);
        }


    private void validateLabScheduleExists(Long id) {
        if (labScheduleMapper.selectById(id) == null) {
            throw exception(LAB_SCHEDULE_NOT_EXISTS);
        }
    }

    @Override
    public LabScheduleDO getLabSchedule(Long id) {
        return labScheduleMapper.selectById(id);
    }

    @Override
    public PageResult<LabScheduleDO> getLabSchedulePage(LabSchedulePageReqVO pageReqVO) {
        return labScheduleMapper.selectPage(pageReqVO);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public LabScheduleImportRespVO importLabScheduleList(List<LabScheduleImportExcelVO> importLabSchedules, Boolean updateSupport) {
        log.info("开始导入机房实训室课，解析到的数据条数: {}", importLabSchedules == null ? 0 : importLabSchedules.size());
        if (CollUtil.isEmpty(importLabSchedules)) {
            log.warn("导入的机房实训室课数据为空");
            throw exception(LAB_SCHEDULE_IMPORT_LIST_IS_EMPTY);
        }

        LabScheduleImportRespVO respVO = LabScheduleImportRespVO.builder()
                .createLabScheduleCount(0).updateLabScheduleCount(0).failureLabScheduleCount(0)
                .failureLabScheduleMessages(new ArrayList<>()).build();

        // 如果支持更新，先删除所有现有数据
        if (updateSupport) {
            log.info("支持更新模式：删除所有现有数据");
            labScheduleMapper.delete(new LambdaQueryWrapperX<>());
            log.info("已删除所有现有的机房实训室课数据");
        }

        // 处理所有导入数据，不进行重复检查
        for (int i = 0; i < importLabSchedules.size(); i++) {
            LabScheduleImportExcelVO importLabSchedule = importLabSchedules.get(i);
            try {
                log.info("处理导入数据 第{}行: 学期={}, 机房={}, 节次={}",
                    i + 1, importLabSchedule.getTerm(), importLabSchedule.getLabName(), importLabSchedule.getClassSection());

                // 校验数据
                validateLabScheduleForImport(importLabSchedule);

                // 直接插入数据，不进行重复检查
                LabScheduleDO labSchedule = BeanUtils.toBean(importLabSchedule, LabScheduleDO.class);
                labScheduleMapper.insert(labSchedule);
                respVO.setCreateLabScheduleCount(respVO.getCreateLabScheduleCount() + 1);

                log.info("成功插入第{}行数据", i + 1);

            } catch (Exception ex) {
                // 记录失败的数据
                respVO.setFailureLabScheduleCount(respVO.getFailureLabScheduleCount() + 1);
                respVO.getFailureLabScheduleMessages().add(String.format("第 %d 行：%s", i + 1, ex.getMessage()));
                log.error("第{}行数据插入失败: {}", i + 1, ex.getMessage());
            }
        }

        // 暂时完全移除相关数据处理，确保主功能稳定
        // processRelatedDataAsync(importLabSchedules);

        return respVO;
    }

    private void validateLabScheduleForImport(LabScheduleImportExcelVO importLabSchedule) {
        if (StrUtil.isEmpty(importLabSchedule.getTerm())) {
            throw exception(LAB_SCHEDULE_TERM_NOT_NULL);
        }
        if (StrUtil.isEmpty(importLabSchedule.getLabName())) {
            throw exception(LAB_SCHEDULE_LAB_NAME_NOT_NULL);
        }
        if (StrUtil.isEmpty(importLabSchedule.getClassSection())) {
            throw exception(LAB_SCHEDULE_CLASS_SECTION_NOT_NULL);
        }

        // 额外验证：确保关键字段不是空白字符
        if (StrUtil.isBlank(importLabSchedule.getTerm()) ||
            StrUtil.isBlank(importLabSchedule.getLabName()) ||
            StrUtil.isBlank(importLabSchedule.getClassSection())) {
            throw new RuntimeException("学期、机房名称、节次信息不能为空白字符");
        }
    }










}